﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.IO;
using System.Drawing.Drawing2D;
using System.Diagnostics;
using Buccaneer;
using Buccontrols;

namespace Buccontrols
{
    #region Enums

    public enum ButtonState { Normal = 0, Hovered = 1, Clicked = 2, Focussed = 3, Disabled = 4, Error = 5 }

    #endregion

    public class IconButton : Panel
    {
        #region Constructor

        public IconButton()
        {
            this.Initialize();

            SetStyle(ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true);

            g = this.CreateGraphics();
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            this.OnPaint(null);
        }

        public IconButton(Point ini_point, Size ini_size)
        {
            this.Initialize();

            this.Size = ini_size;
            this.Location = ini_point;

            g = this.CreateGraphics();
            g.SmoothingMode = SmoothingMode.None;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
        }

        public void Initialize()
        {
            this.Size = new Size(119, 100);
            this.picture = new Bitmap(100, 200);
            this.text = "nix";
            this.BackgroundImageLayout = ImageLayout.Stretch;

            this.SizeChanged += new EventHandler(panel_sizeChanged);
            this.UpdateImage();

            //set events
            this.MouseLeave += new EventHandler(BitmapButton_MouseLeave);
            this.MouseEnter += new EventHandler(BitmapButton_MouseEnter);
            this.MouseDown += new MouseEventHandler(BitmapButton_MouseDown);
            this.MouseUp += new MouseEventHandler(BitmapButton_MouseUp);
            this.GotFocus += new EventHandler(BitmapButton_GotFocus);
        }

        #endregion

        #region OnPaint

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            
            //*/

            try
            {
                g.DrawImage(
                    BitmapHandler.resizeImage(
                    picture,
                    new Size(
                            this.Size.Height - (int)(.3 * this.Size.Height),
                            this.Size.Height - (int)(.3 * this.Size.Height)
                        )),
                    new Rectangle(
                        new Point(
                            (int)((this.Size.Width - (this.Size.Height - (int)(.3 * this.Size.Height))) / 2),
                            (int)(.1 * this.Size.Height)
                        ),
                        new Size(
                            this.Size.Height - (int)(.3 * this.Size.Height),
                            this.Size.Height - (int)(.3 * this.Size.Height)
                        )
                    )
                );
            }
            catch (Exception)
            {
                g = this.CreateGraphics();
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                try
                {
                    g.DrawImage(
                        BitmapHandler.resizeImage(
                        picture,
                        new Size(
                                this.Size.Height - (int)(.3 * this.Size.Height),
                                this.Size.Height - (int)(.3 * this.Size.Height)
                            )),
                        new Rectangle(
                            new Point(
                                (int)((this.Size.Width - (this.Size.Height - (int)(.3 * this.Size.Height))) / 2),
                                (int)(.1 * this.Size.Height)
                            ),
                            new Size(
                                this.Size.Height - (int)(.3 * this.Size.Height),
                                this.Size.Height - (int)(.3 * this.Size.Height)
                            )
                        )
                    );
                }
                catch (Exception ex)
                {
                    Options.WriteComment("(!) Error in drawing string: " + ex.Source);
                }
            }
            //*/

            try
            {
                g.DrawString(
                    text,
                    new Font(Options.Font.Name, .1f * this.Size.Height, Options.Font.Style, Options.Font.Unit, Options.Font.GdiCharSet, Options.Font.GdiVerticalFont),
                    Brushes.Black,
                    new Rectangle(
                        new Point(
                            (int)((this.Size.Width - g.MeasureString(text, new Font(Options.Font.Name, .1f * this.Size.Height, Options.Font.Style, Options.Font.Unit, Options.Font.GdiCharSet, Options.Font.GdiVerticalFont)).Width) / 2),
                            (int)(.1 * this.Size.Height) + (this.Size.Height - (int)(.3 * this.Size.Height))
                        ),
                        new Size(
                            this.Width,
                            (int)(.2f * this.Size.Height))
                        )
                    );
            }
            catch (Exception ex) { Options.WriteComment("(!) Error in drawing string: " + ex.Source); }

        }

        #endregion

        #region Private Attributes

        Graphics g;

        static Image normal, hovered, clicked, focussed, disabled, error;
        string text;
        Image picture;
        ButtonState currentState;

        #endregion

        #region Public Attributes

        public Image ImageNormal
        {
            get { return normal; }
        }

        public Image ImageHovered
        {
            get { return hovered; }
        }

        public Image ImageClicked
        {
            get { return clicked; }
        }

        public Image ImageFocussed
        {
            get { return focussed; }
        }

        public Image ImageDisabled
        {
            get { return disabled; }
        }

        public Image Icon
        {
            get { return picture; }
            set
            {
                picture = value;
                this.Refresh();
            }
        }

        public ButtonState CurrentState
        {
            get { return currentState; }
        }

        public override String Text
        {
            get { return text; }
            set { text = value; }
        }

        #endregion

        #region Public Functions

        public static void LoadImages()
        {
            // Load all images from Layout Dir
            string s = Options.LayoutFolder + "listviewButton.png";
            normal = new Bitmap(s);
            hovered = new Bitmap(Options.LayoutFolder + "listviewButtonHover.png");
            clicked = new Bitmap(Options.LayoutFolder + "listviewButtonClick.png");
            focussed = new Bitmap(Options.LayoutFolder + "listviewButtonFocus.png");
            disabled = new Bitmap(Options.LayoutFolder + "listviewButtonDisabled.png");
            error = new Bitmap(Options.LayoutFolder + "listviewButtonError.png");
        }

        public void UpdateImage()
        {
            Image img;

            if (normal == null) LoadImages();

            switch (currentState)
            {
                case ButtonState.Normal:
                    img = normal;
                    break;
                case ButtonState.Hovered:
                    img = hovered;
                    break;
                case ButtonState.Clicked:
                    img = clicked;
                    break;
                case ButtonState.Focussed:
                    img = focussed;
                    break;
                case ButtonState.Disabled:
                    img = disabled;
                    break;
                default:
                    img = error;
                    break;
            }

            BackgroundImage = new Bitmap(img, this.Size);
        }

        #endregion

        #region Private Functions

        private void changeState(ButtonState newState)
        {
            currentState = newState;
            UpdateImage();
        }

        #endregion

        #region Private Eventhandlers

        private void panel_sizeChanged(object sender, EventArgs e)
        {
            this.Size = new Size((int)(this.Size.Height * 1.19), this.Size.Height);
        }

        void BitmapButton_GotFocus(object sender, EventArgs e)
        {
            if ((byte)currentState < 4)
                changeState(ButtonState.Focussed);
        }

        void BitmapButton_MouseUp(object sender, MouseEventArgs e)
        {
            if ((byte)currentState < 4)
                changeState(ButtonState.Hovered);
        }

        void BitmapButton_MouseEnter(object sender, EventArgs e)
        {
            if ((byte)currentState < 4)
                changeState(ButtonState.Hovered);
        }

        void BitmapButton_MouseDown(object sender, MouseEventArgs e)
        {
            if ((byte)currentState < 4)
                changeState(ButtonState.Clicked);
        }

        void BitmapButton_MouseLeave(object sender, EventArgs e)
        {
            if ((byte)currentState < 4)
                changeState(ButtonState.Normal);
        }

        #endregion
    }
}
